<?php

use think\Lang;
use think\Db;
use fast\Form;
use fast\Tree;
use app\common\model\Category;

error_reporting(E_ERROR | E_PARSE );

// 公共助手函数

if (!function_exists('__'))
{

    /**
     * 获取语言变量值
     * @param string    $name 语言变量名
     * @param array     $vars 动态变量值
     * @param string    $lang 语言
     * @return mixed
     */
    function __($name, $vars = [], $lang = '')
    {
        if (is_numeric($name))
            return $name;
        if (!is_array($vars))
        {
            $vars = func_get_args();
            array_shift($vars);
            $lang = '';
        }
        return Lang::get($name, $vars, $lang);
    }

}

if (!function_exists('format_bytes'))
{

    /**
     * 将字节转换为可读文本
     * @param int $size 大小
     * @param string $delimiter 分隔符
     * @return string
     */
    function format_bytes($size, $delimiter = '')
    {
        $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
        for ($i = 0; $size >= 1024 && $i < 6; $i++)
            $size /= 1024;
        return round($size, 2) . $delimiter . $units[$i];
    }

}

if (!function_exists('datetime'))
{

    /**
     * 将时间戳转换为日期时间
     * @param int $time 时间戳
     * @param string $format 日期时间格式
     * @return string
     */
    function datetime($time, $format = 'Y-m-d H:i:s')
    {
        $time = is_numeric($time) ? $time : strtotime($time);
        return date($format, $time);
    }

}

/**
 * XML转数组
 * @param string $arr
 * @param boolean $isnormal
 * @return array
 */
function xml2array($xml, $isnormal = false) {
    $xml_parser = new \app\common\library\Xml($isnormal);
    $data = $xml_parser->parse($xml);
    $xml_parser->destruct();
    return $data;
}

/**
 * 数组转XML
 * @param array $arr
 * @param boolean $htmlon
 * @param boolean $isnormal
 * @param intval $level
 * @return type
 */
function array2xml($arr, $htmlon = TRUE, $isnormal = FALSE, $level = 1) {
    $s = $level == 1 ? "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n<root>\r\n" : '';
    $space = str_repeat("\t", $level);
    foreach($arr as $k => $v) {
        if(!is_array($v)) {
            $s .= $space."<item id=\"$k\">".($htmlon ? '<![CDATA[' : '').$v.($htmlon ? ']]>' : '')."</item>\r\n";
        } else {
            $s .= $space."<item id=\"$k\">\r\n".array2xml($v, $htmlon, $isnormal, $level + 1).$space."</item>\r\n";
        }
    }
    $s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s);
    return $level == 1 ? $s."</root>" : $s;
}

/**
 * 生成表格操作按钮栏
 * @param array $btns 按钮组
 * @param array $attr 按钮属性值
 * @return string
 */
function build_toolbar($btns = NULL, $attr = [])
{
    $auth = \app\admin\library\Auth::instance();
    $controller = str_replace('.', '/', strtolower(think\Request::instance()->controller()));
    $btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del'];
    $btns = is_array($btns) ? $btns : explode(',', $btns);
    $index = array_search('delete', $btns);
    if ($index !== FALSE)
    {
        $btns[$index] = 'del';
    }
    $btnAttr = [
        'back'    => ['javascript:;', 'btn btn-primary btn-info', 'fa fa-mail-reply-all', __('back')],
        'refresh' => ['javascript:;', 'btn btn-primary btn-refresh', 'fa fa-refresh', ''],
        'add'     => ['javascript:;', 'btn btn-success btn-add', 'fa fa-plus', __('Add')],
        'edit'    => ['javascript:;', 'btn btn-success btn-edit btn-disabled disabled', 'fa fa-pencil', __('Edit')],
        'del'     => ['javascript:;', 'btn btn-danger btn-del btn-disabled disabled', 'fa fa-trash', __('Delete')],
    ];
    $btnAttr = array_merge($btnAttr, $attr);
    $html = [];
    foreach ($btns as $k => $v)
    {
        //如果未定义或没有权限
        if (!isset($btnAttr[$v]) || ($v !== 'refresh' && !$auth->check("{$controller}/{$v}")))
        {
            continue;
        }
        list($href, $class, $icon, $text, $extra) = $btnAttr[$v];
        $html[] = '<a href="' . $href . '" class="' . $class . '" '. $extra .'><i class="' . $icon . '"></i> ' . $text . '</a>';
    }
    return implode(' ', $html);
}


/**
 * 生成页面Heading
 *
 * @param string $title
 * @param string $content
 * @return string
 */
function build_heading($title = NULL, $content = NULL)
{
    if (is_null($title) && is_null($content))
    {
        $path = request()->pathinfo();
        $path = $path[0] == '/' ? $path : '/' . $path;
        // 根据当前的URI自动匹配父节点的标题和备注
        $data = Db::name('auth_rule')->where('name', $path)->field('title,remark')->find();
        if ($data)
        {
            $title = $data['title'];
            $content = $data['remark'];
        }
    }
    if (!$content)
        return '';
    return '<div class="panel-heading"><div class="panel-lead"><em>' . $title . '</em>' . $content . '</div></div>';
}

/**
 * 生成单选按钮组
 * @param string $name
 * @param array $list
 * @param mixed $selected
 * @return string
 */
function build_radios($name, $list = [], $selected = null)
{
    $html = [];
    $selected = is_null($selected) ? key($list) : $selected;
    $selected = is_array($selected) ? $selected : explode(',', $selected);
    foreach ($list as $k => $v)
    {
        $html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::radio($name, $k, in_array($k, $selected), ['id' => "{$name}-{$k}"]));
    }
    return implode(' ', $html);
}

/**
 * 生成下拉列表
 * @param string $name
 * @param mixed $options
 * @param mixed $selected
 * @param mixed $attr
 * @return string
 */
function build_select($name, $options, $selected = [], $attr = [])
{
    $options = is_array($options) ? $options : explode(',', $options);
    $selected = is_array($selected) ? $selected : explode(',', $selected);
    return Form::select($name, $options, $selected, $attr);
}

/**
 * 生成复选按钮组
 * @param string $name
 * @param array $list
 * @param mixed $selected
 * @return string
 */
function build_checkboxs($name, $list = [], $selected = null)
{
    $html = [];
    $selected = is_null($selected) ? [] : $selected;
    $selected = is_array($selected) ? $selected : explode(',', $selected);
    foreach ($list as $k => $v)
    {
        $html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::checkbox($name, $k, in_array($k, $selected), ['id' => "{$name}-{$k}"]));
    }
    return implode(' ', $html);
}

/**
 * 生成分类下拉列表框
 * @param string $name
 * @param string $type
 * @param mixed $selected
 * @param array $attr
 * @return string
 */
function build_category_select($name, $type, $selected = null, $attr = [], $header = [])
{
    $tree = Tree::instance();
    $tree->init(Category::getCategoryArray($type), 'pid');
    $categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');
    $categorydata = $header ? $header : [];
    foreach ($categorylist as $k => $v)
    {
        $categorydata[$v['id']] = $v['name'];
    }
    $attr = array_merge(['id' => "c-{$name}", 'class' => 'form-control selectpicker'], $attr);
    return build_select($name, $categorydata, $selected, $attr);
}

/**
 * 哈希值加解密
 * @param  string $id    加解密字符串
 * @param  string $type  方法（加密encode;解密decode）
 * @param  string $bit   字符串长度
 * @return string
 */
function hashids($id = '',$type = 'encode',$bit = 14){
    $cls = new \Hashids\Hashids('', $bit);
    $result = $cls->$type($id);
    return ($type == 'encode') ? $result : $result[0];
}

/**
 * 保留多位小数，且不四舍五入
 * @param $number 数值
 * @param $bit  保留小数位数
 */
function decimal($number ,$bit = 2) {
    $bcpow = bcpow(10,$bit);
    $num = explode('.', $number * $bcpow);
    $number = $num[0]/$bcpow;
    return number_format($number,$bit,'.','');
}

/**
 * 加密字符串
 * @param string $str 字符串
 * @param string $key 加密key
 * @return string
 */
function encrypt($data,$key = '',$expire = 0) {
    $expire = sprintf('%010d', $expire ? $expire + time():0);
    $key = md5($key != '' ? $key : config('authkey'));
    $data = base64_encode($expire.$data);
    $x    = 0;
    $len  = strlen($data);
    $l    = strlen($key);
    $char = $str    =   '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    for ($i = 0; $i < $len; $i++) {
        $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1)))%256);
    }
    return str_replace(array('+','/','='),array('-','_',''),base64_encode($str));
}

/**
 * 解密字符串
 * @param string $str 字符串
 * @param string $key 加密key
 * @return string
 */
function decrypt($data,$key = '') {
    $key = md5($key != '' ? $key : config('authkey'));
    $data   = str_replace(array('-','_'),array('+','/'),$data);
    $mod4   = strlen($data) % 4;
    if ($mod4) {
       $data .= substr('====', $mod4);
    }
    $data   = base64_decode($data);

    $x      = 0;
    $len    = strlen($data);
    $l      = strlen($key);
    $char   = $str = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    for ($i = 0; $i < $len; $i++) {
        if (ord(substr($data, $i, 1))<ord(substr($char, $i, 1))) {
            $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
        }else{
            $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
        }
    }
    $data   = base64_decode($str);
    $expire = substr($data,0,10);
    if($expire > 0 && $expire < time()) {
        return '';
    }
    $data   = substr($data,10);
    return $data;
}

/**
 * 数组过滤(包含多维)
 */
function muilt_array_filter($arr) {
    foreach ($arr as $k => $v) {
        if(is_array($arr[$k])) {
            $arr[$k] = muilt_array_filter($arr[$k]);
            if (empty($arr[$k])) {
                unset($arr[$k]);
            }
        } else {
            if(trim($arr[$k]) === '') {
                unset($arr[$k]);
            }
        }
    }
    return $arr;
}

/**
*截取字符串,汉字占两个字节，字母占一个字节
*页面编码必须为utf-8
*/
function esub($str,$start = 0, $length = 0,$ext = "..."){

    if($length < 1){
        return $str;
    }

    //计算字符串长度
    $strlen = (strlen($str) + mb_strlen($str,"UTF-8")) / 2;
    if($strlen < $length){
        return $str;
    }

    if(mb_check_encoding($str,"UTF-8")){
        $str = mb_strcut(mb_convert_encoding($str, "GBK","UTF-8"), $start, $length, "GBK");
        $str = mb_convert_encoding($str, "UTF-8", "GBK");
    }else{
        return "不支持的文档编码";
    }
    return $str.$ext;
}